import moment from 'moment';
import { stringify } from 'qs';
import { getFormatByUnit, getLeaveUnit } from '@/pages/Flow/Mine/ApplyPage/utils';
import request from '@/utils/request';
import { getDuration, getDurationFlexible } from '@/utils/utils';
import { getTotalExpense } from '@/components/JsonForm/utils';
import { dictionaryList } from '@/services/dictionary';
import { getDataSource } from '@/components/Custom/Time/Time';
import { getTime } from '@/components/Custom/CustomDatePicker/CustomDatePicker';
import { modifyProps } from '@/pages/Flow/Mine/Apply/utils';
import FORM_TYPE_MAP from './consts';
import { getTimeExtraParam } from './utils';

const concatTime = ({ time, timeValue }) => {
    if (!timeValue) return time;
    return moment(moment(`${time.format('YYYY-MM-DD')} ${timeValue}:00`));
};

const fetchTimeCount = async (name, value, setDuration, form, formType, leaveTypeList, country, json = {}, setJson) => {
    const { fields } = json;
    const currentUser = localStorage.getItem('user') ? JSON.parse(localStorage.getItem('user')) : {};
    const { firstCompanyCode } = currentUser?.firstOrgInfo;
    if (!value || !value.time) {
        form.setFieldsValue({
            duration: ''
        });
        setDuration('');
        return;
    }

    if (formType === FORM_TYPE_MAP.TYPE_LEAVE) {
        const { leaveType, startTime, endTime } = form.getFieldsValue();
        const find = leaveTypeList.find(item => item.leaveCode === leaveType);
        if (!find) return;
        if (value.unit === 2 && !value.dayType) return;
        if (name === 'startTime' && !endTime.time) return;
        if (name === 'endTime' && !startTime.time) return;
        if (name === 'startTime' && endTime.unit === 2 && !endTime.dayType) return;
        if (name === 'endTime' && startTime.unit === 2 && !startTime.dayType) return;
        const currentStart = name === 'startTime' ? value : startTime;
        const currentEnd = name === 'endTime' ? value : endTime;
        const s = concatTime(currentStart);
        const e = concatTime(currentEnd);
        // 如果开始时间和结束时间不正确，则不请求时长
        if (s.isValid() && e.isValid()) {
            setJson({
                ...json,
                fields: modifyProps(
                    'leaveType',
                    {
                        startTime: moment(s).format('YYYY-MM-DD hh:mm:00'),
                        endTime: moment(e).format('YYYY-MM-DD hh:mm:00')
                    },
                    fields
                )
            });

            // 上午下午类型要加参数
            const extra = getTimeExtraParam(currentStart, currentEnd, value.unit);
            const postStartTime = getFormatByUnit('startTime', country, find.leaveUnit, s);
            const postEndTime = getFormatByUnit('endTime', country, find.leaveUnit, e);

            const result = await request('/api/work/v1/attendance/flow/web/flowlong', {
                method: 'POST',
                data: {
                    attendanceFlowType: 'leave',
                    companyId: currentUser.companyId,
                    startTime: postStartTime,
                    endTime: postEndTime,
                    leaveCode: leaveType,
                    flowTimeUnit: value.unit,
                    ...extra
                }
            });

            if (result.code === 10000) {
                form.setFieldsValue({
                    duration: getDurationFlexible(result.data, find.leaveUnit)
                });
                setDuration(result.data);
            } else {
                form.setFields({
                    duration: {
                        value: 0,
                        errors: [new Error(result.msg)]
                    }
                });
                setDuration('');
            }
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_OVER_TIME) {
        const { overTimeType, startTime, endTime } = form.getFieldsValue();
        if (name === 'startTime' && !endTime.time) return;
        if (name === 'endTime' && !startTime.time) return;
        const result = await request('/api/work/v1/attendance/leaveflow/web/overlong', {
            method: 'POST',
            data: {
                companyCode: firstCompanyCode,
                startTime: getFormatByUnit('startTime', country, 3, name === 'startTime' ? value.time : startTime.time),
                endTime: getFormatByUnit('endTime', country, 3, name === 'endTime' ? value.time : endTime.time),
                overType: overTimeType
            }
        });

        if (result.code === 10000) {
            form.setFieldsValue({
                duration: getDuration(result.data, 3)
            });
            setDuration(result.data);
        } else {
            form.setFields({
                duration: {
                    value: 0,
                    errors: [new Error(result.msg)]
                }
            });
            setDuration('');
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_GO_OUT) {
        const { startTime, endTime } = form.getFieldsValue();
        if (name === 'startTime' && !endTime.time) return;
        if (name === 'endTime' && !startTime.time) return;
        const result = await request('/api/work/v1/attendance/leaveflow/web/outlong', {
            method: 'POST',
            data: {
                companyId: currentUser.companyId,
                startTime: getFormatByUnit('startTime', country, 3, name === 'startTime' ? value.time : startTime.time),
                endTime: getFormatByUnit('endTime', country, 3, name === 'endTime' ? value.time : endTime.time)
            }
        });

        if (result.code === 10000) {
            form.setFieldsValue({
                duration: getDuration(result.data, 3)
            });
            setDuration(result.data);
        } else {
            form.setFields({
                duration: {
                    value: 0,
                    errors: [new Error(result.msg)]
                }
            });
            setDuration('');
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_ON_BUSINESS) {
        const { startTime, endTime } = form.getFieldsValue();
        if (name === 'startTime' && !endTime.time) return;
        if (name === 'endTime' && !startTime.time) return;
        if (!value) return;
        const currentStart = name === 'startTime' ? value : startTime;
        const currentEnd = name === 'endTime' ? value : endTime;
        const extra = getTimeExtraParam(currentStart, currentEnd, value.unit);
        const postStartTime = getFormatByUnit('startTime', country, 2, currentStart.time);
        const postEndTime = getFormatByUnit('endTime', country, 2, currentEnd.time);
        const result = await request('/api/work/v1/attendance/flow/web/flowlong', {
            method: 'POST',
            data: {
                attendanceFlowType: 'onBusiness',
                companyId: currentUser.companyId,
                startTime: postStartTime,
                endTime: postEndTime,
                flowTimeUnit: value.unit,
                ...extra
            }
        });

        if (result.code === 10000) {
            form.setFieldsValue({
                duration: getDurationFlexible(result.data, 2)
            });
            setDuration(result.data);
        } else {
            form.setFields({
                value: 0,
                duration: {
                    errors: [new Error(result.msg)]
                }
            });
            setDuration('');
        }
    }
};

// 获取表单对应 field 的最新值
const getCurrentFieldValue = ({ field, value, id, form }) => {
    if (field === id) return value;
    return form.getFieldValue(field);
};

/**
 * 处理表单项 change 事件
 * @param params
 */
const dealFieldChange = async params => {
    const {
        id,
        value,
        formType,
        form,
        country,
        json,
        setJson,
        currentUser,
        leaveTypeList,
        overtimeList,
        postList,
        takeUsers,
        reason1,
        setPostId,
        setReason2,
        setDuration,
        setAttachmentRequired,
        setOriginInstitutionName,
        setCurPost,
        setIsDataReady
    } = params;
    setIsDataReady(false);

    const tempJson = { ...json };
    const { fields } = tempJson;
    const item = fields.find(_item => _item.id === id);

    // 请假申请
    if (formType === FORM_TYPE_MAP.TYPE_LEAVE) {
        const unit = getLeaveUnit(item.params.component.props.data, value);
        if (id === 'leaveType') {
            const dataSource = getDataSource(15);
            const nextTime = dataSource.find(newItem => newItem >= moment().format('HH:mm'));
            const endNextTime = moment(moment(nextTime, 'HH:mm').add(60, 'm')).format('HH:mm');
            if (value === 'CommonSick') {
                setAttachmentRequired(true);
            } else {
                setAttachmentRequired(false);
            }
            form.setFieldsValue(
                {
                    startTime: {
                        ...form.getFieldValue('startTime'),
                        time: getTime({
                            date: moment(),
                            dayType: 'am',
                            unit,
                            country,
                            type: 'startTime'
                        }),
                        timeValue: unit === 3 ? nextTime : '',
                        dayType: '',
                        disabled: false,
                        unit
                    },
                    endTime: {
                        ...form.getFieldValue('endTime'),
                        time: getTime({
                            date: moment(),
                            dayType: 'pm',
                            unit,
                            country,
                            type: 'endTime'
                        }),
                        timeValue: unit === 3 ? endNextTime : '',
                        dayType: '',
                        disabled: false,
                        unit
                    },
                    duration: ''
                },
                () => {
                    fetchTimeCount(
                        'startTime',
                        {
                            ...form.getFieldValue('startTime')
                        },
                        setDuration,
                        form,
                        formType,
                        leaveTypeList,
                        country,
                        json,
                        setJson
                    );
                }
            );
            form.validateFields(['startTime', 'endTime'], {
                force: true
            });
        }
        // 计算时长
        if (id === 'startTime') {
            // form.validateFields(['endTime'], { force: true });
            if (form.getFieldValue('endTime')) {
                const endTimeValue = form.getFieldValue('endTime');
                // 结束时间多 1 个小时
                form.setFieldsValue(
                    {
                        endTime: {
                            ...endTimeValue,
                            timeValue: value.timeValue
                                ? moment(moment(value.timeValue, 'HH:mm').add(60, 'm')).format('HH:mm')
                                : ''
                        }
                    },
                    () => {
                        // 结束时间赋值完成后需要获取时长
                        fetchTimeCount(
                            'startTime',
                            value,
                            setDuration,
                            form,
                            formType,
                            leaveTypeList,
                            country,
                            json,
                            setJson
                        );
                    }
                );
            } else {
                form.setFieldsValue({ endTime: undefined });
            }
        }
        // 计算时长
        if (id === 'endTime') {
            // form.validateFields(['startTime'], { force: true });
            if (form.getFieldValue('startTime')) {
                fetchTimeCount('endTime', value, setDuration, form, formType, leaveTypeList, country, json, setJson);
            } else {
                form.setFieldsValue({ startTime: undefined });
            }
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_OVER_TIME) {
        if (id === 'overTimeType') {
            form.setFieldsValue({
                startTime: {
                    ...form.getFieldValue('startTime'),
                    time: undefined,
                    dayType: '',
                    disabled: false,
                    unit: 3
                },
                endTime: {
                    ...form.getFieldValue('endTime'),
                    time: undefined,
                    dayType: '',
                    disabled: false,
                    unit: 3
                },
                duration: ''
            });
            form.validateFields(['startTime', 'endTime'], { force: true });
        }
        // 计算时长
        if (id === 'startTime') {
            if (form.getFieldValue('endTime')) {
                fetchTimeCount('startTime', value, setDuration, form, formType, leaveTypeList, country, overtimeList);
            } else {
                form.setFieldsValue({ endTime: undefined });
            }
        }
        // 计算时长
        if (id === 'endTime') {
            // form.validateFields(['startTime'], { force: true });
            if (form.getFieldValue('startTime')) {
                fetchTimeCount('endTime', value, setDuration, form, formType, leaveTypeList, country, overtimeList);
            } else {
                form.setFieldsValue({ startTime: undefined });
            }
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_GO_OUT) {
        // 计算时长
        if (id === 'startTime') {
            if (form.getFieldValue('endTime')) {
                fetchTimeCount('startTime', value, setDuration, form, formType, leaveTypeList, country);
            } else {
                form.setFieldsValue({ endTime: undefined });
            }
        }
        // 计算时长
        if (id === 'endTime') {
            // form.validateFields(['startTime'], { force: true });
            if (form.getFieldValue('startTime')) {
                fetchTimeCount('endTime', value, setDuration, form, formType, leaveTypeList, country);
            } else {
                form.setFieldsValue({ startTime: undefined });
            }
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_RESIGN_IN) {
        if (id === 'type') {
            form.setFieldsValue({
                startTime: {
                    ...form.getFieldValue('startTime'),
                    time: undefined,
                    dayType: '',
                    disabled: false,
                    unit: 3
                }
            });
            // form.validateFields(['startTime'], { force: true });
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_ON_BUSINESS) {
        let total = 0;
        const { hotelExpense, transportExpense, businessAllowance, otherExpense } = form.getFieldsValue();
        // 计算时长
        if (id === 'startTime') {
            if (form.getFieldValue('endTime')) {
                fetchTimeCount('startTime', value, setDuration, form, formType, leaveTypeList, country, overtimeList);
            } else {
                form.setFieldsValue({ endTime: undefined });
            }
        }
        // 计算时长
        if (id === 'endTime') {
            // form.validateFields(['startTime'], { force: true });
            if (form.getFieldValue('startTime')) {
                fetchTimeCount('endTime', value, setDuration, form, formType, leaveTypeList, country, overtimeList);
            } else {
                form.setFieldsValue({ startTime: undefined });
            }
        }

        // 计算总预算
        if (id === 'hotelExpense') {
            total = getTotalExpense(value, transportExpense, businessAllowance, otherExpense);
        }
        if (id === 'transportExpense') {
            total = getTotalExpense(hotelExpense, value, businessAllowance, otherExpense);
        }
        if (id === 'businessAllowance') {
            total = getTotalExpense(hotelExpense, transportExpense, value, otherExpense);
        }
        if (id === 'otherExpense') {
            total = getTotalExpense(hotelExpense, transportExpense, businessAllowance, value);
        }
        if (id === 'hotelExpense' || id === 'transportExpense' || id === 'businessAllowance' || id === 'otherExpense') {
            form.setFieldsValue({
                totalExpense: total.toFixed(2)
            });
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_ON_RECRUIT) {
        if (id === 'recruitPost') {
            const target = postList.find(post => String(post.id) === value);
            form.setFields({
                postLevel: {
                    value: target ? target.postGradeCode : ''
                }
            });
        }
        if (id === 'reason1') {
            form.setFieldsValue({
                reason2: ''
            });
            if (value !== 'quitNeed') {
                const find = reason1.find(reason => reason.dictValue === value);
                if (find && find.remark) {
                    const result = await dictionaryList({
                        code: find.remark
                    });

                    if (result.code === 10000) {
                        setReason2(result.data);
                    }
                }
            }
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_ON_OFFER) {
        if (id === 'yearSalary' || id === 'oldYearSalary') {
            const yearSalaryValue = getCurrentFieldValue({ field: 'yearSalary', id, value, form });
            const oldYearSalaryValue = getCurrentFieldValue({ field: 'oldYearSalary', id, value, form });
            let gainPercentValue = '';
            if (yearSalaryValue && oldYearSalaryValue) {
                gainPercentValue = (((yearSalaryValue - oldYearSalaryValue) / oldYearSalaryValue) * 100).toFixed(2);
            }
            form.setFieldsValue({
                gainPercent: gainPercentValue
            });
        }
        if (id === 'talentName') {
            if (value) {
                const find = takeUsers.find(user => user.candidateCode === value);

                if (find) {
                    form.setFieldsValue({
                        talentSex: find.talentSex || '',
                        talentBirth: {
                            ...form.getFieldValue('talentBirth'),
                            time: find.talentBirth ? moment(find.talentBirth) : null
                        },
                        talentAgree: find.talentDegree || '',
                        entryPost: (find.recruitPostId && String(find.recruitPostId)) || '',
                        demandDepartmentId: find.departmentIds || [],
                        entryLevel: find.postGradeCode || ''
                    });
                    setPostId(find.recruitPostId);
                    setCurPost(find.recruitPost);
                }
            }
        }
    } else if (formType === FORM_TYPE_MAP.TYPE_ON_SYSTEM) {
        if (id === 'institutionType') {
            form.setFieldsValue({ originInstitutionId: '' });
            request(
                `/api/oa/v1/institutions/origin?${stringify({
                    institutionType: value,
                    companyId: currentUser.companyId
                })}`,
                {
                    method: 'GET'
                }
            ).then(response => {
                if (response.code === 10000) {
                    setOriginInstitutionName(response.data);
                }
            });
        }
    }
    setIsDataReady(true);
};

export default dealFieldChange;
